package org.libarae.communication.response;

import java.io.ByteArrayOutputStream;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.libarae.communication.HTTPUtils;
import org.libarae.communication.XmlParseException;
import org.libarae.communication.common.MessageThread;
import org.libarae.communication.common.Type;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MailboxMessagesResponse extends Response {
	private Vector<MessageThread> mMessageThreads = new Vector<MessageThread>();

	public MailboxMessagesResponse(int status) {
		super(Type.MAILBOX_MESSAGES, status);
	}

	public MailboxMessagesResponse(int status, Vector<MessageThread> messageThread) {
		super(Type.MAILBOX_MESSAGES, status);
		setMessageThreads(messageThread);
	}

	@Override
	public String createXML() throws XmlParseException {
		Document doc;
		try {
			// setup the factory to build the xml
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			doc = documentBuilder.newDocument();
		}
		catch (Exception e) {
			throw new XmlParseException("Error creating XML Builder", e);
		}

		// create the xml
		Element rootElement = doc.createElement("type");
		rootElement.setAttribute("typeID", super.getType() + "");
		doc.appendChild(rootElement);
		// user name
		Element node = doc.createElement("mStatus");
		node.setTextContent(getStatus() + "");
		rootElement.appendChild(node);

		// put vector in to the xml
		node = doc.createElement("mMessageThreads");
		for (MessageThread mesT : mMessageThreads) {
			Element subNode = doc.createElement("MessageThread");
			mesT.createXml(doc, subNode);
			node.appendChild(subNode);
		}
		rootElement.appendChild(node);

		// export the xml to a string
		String output = null;
		try {
			ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(byteArrayOutput);
			transformer.transform(source, result);
			output = byteArrayOutput.toString();
		}
		catch (Exception e) {
			throw new XmlParseException("Error outputting XML to string", e);
		}

		// return the string
		return output;
	}

	@Override
	public void decodeXML(Document document) {
		// get the document root and node list
		Element root = document.getDocumentElement();
		NodeList nodeList = root.getChildNodes();

		// set all of the nodes in their proper places
		for (int i = 0; i < nodeList.getLength(); i++) {
			// find what node we have
			String nodeName = nodeList.item(i).getNodeName();
			if (nodeName.equals("mStatus")) {
				setStatus(Integer.parseInt(nodeList.item(i).getTextContent()));
			}
			else if (nodeName.equals("mMessageThreads")) {
				NodeList nodeVector = nodeList.item(i).getChildNodes();
				mMessageThreads = new Vector<MessageThread>();
				for (int p = 0; p < nodeVector.getLength(); p++) {
					MessageThread mesTh = new MessageThread();
					mesTh.decodeXML(nodeVector.item(p));
					mMessageThreads.add(mesTh);
				}
			}
			else {
				System.err.println("Unknow field in object XML: " + nodeName);
			}
		}
	}

	/**
	 * @return the mMessageThreads
	 */
	public Vector<MessageThread> getMessageThreads() {
		return mMessageThreads;
	}

	/**
	 * @param mMessageThreads
	 *            the mMessageThreads to set
	 */
	public void setMessageThreads(Vector<MessageThread> mMessageThreads) {
		if (mMessageThreads == null)
			this.mMessageThreads = new Vector<MessageThread>();
		else
			this.mMessageThreads = mMessageThreads;
	}

	@Override
	public String createHTML() {
		Vector<MessageThread> mst = getMessageThreads();

		if (mst.isEmpty())
			return HTTPUtils.HTMLPageHeader("") + "<div class=\"holder\"><center><br/>You have no messages.</div></center></body>";

		StringBuilder sb = new StringBuilder();
		sb.append("<div class=\"holder\">");
		for (MessageThread messageThread : getMessageThreads()) {
			String background = "white";
			if(messageThread.isHasUnRead())
				background = "#E5ECFF";
			sb.append("\n<div style=\"background:"+background+";\" class=\"bookHolder\" onclick=\"location.href='/message.html?mThreadId=" + HTTPUtils.encodeURL("" + messageThread.getThreadId()) + "';\">");
			String title = messageThread.getSubject();
			if (title.length() > 30)
				title = title.substring(0, 30) + "..";
			sb.append("<strong>"+formatTime(messageThread.getTime())+"</strong>: ");
			sb.append("<i>").append(title).append("</i>");			
			sb.append("<br/>Between: ").append(messageThread.getUserName1() + " and " + messageThread.getUserName2());
			sb.append("<div style=\"float:right;\"><a class=\"nounderline\" href=\"/message.html?mThreadId=" + HTTPUtils.encodeURL("" + messageThread.getThreadId()) + "\" > Details </a></div>");
			sb.append("</div>");
		}

		int page = Integer.parseInt(getHtmlHelperMessage());

		if (page > 0) {
			sb.append("<a class=\"nounderline\" href=\"messages.html?mMailPageNumber=" + (page - 1) + "\">");
			sb.append("<div style=\"float:left;font-size:17px;padding:15px;\">&lt; Previous Page</div>").append("</a>");
		}

		sb.append("<a class=\"nounderline\" href=\"messages.html?mMailPageNumber=" + (page + 1) + "\">");
		sb.append("<div style=\"float:right;font-size:17px;padding:15px;\">Next Page &gt;</div>").append("</a>");

		sb.append("</div></center></body>");
		return HTTPUtils.HTMLPageHeader("") + sb;
	}

	public String formatTime(long time) {
		time = time / 1000;
		String seconds = Integer.toString((int) (time % 60));
		String minutes = Integer.toString((int) ((time % 3600) / 60));
		int hoursInt = (int)(time / 3600);
		int devide = ((int)hoursInt % 24)-4;
		
		String hours = Integer.toString(devide);

		if (seconds.length() < 2) {
			seconds = "0" + seconds;
		}
		if (minutes.length() < 2) {
			minutes = "0" + minutes;
		}
		if (hours.length() < 2) {
			hours = "0" + hours;
		}
		return hours+":"+minutes+":"+seconds;
	}
}
